﻿using System;
using UnityEngine;
using UnityEngine.EventSystems;

namespace Core
{
    public class LongPressListener : MonoBehaviour,
        IPointerDownHandler,
        IPointerUpHandler,
        IPointerExitHandler
    {
        public enum EEvtKind
        {
            Down,
            Press,
            Up
        }

        public event Action<EEvtKind, LongPressListener> onEvent;

        private bool mIsdown = false;
        private float mDelaytime = 0.5f;
        private float mIntervaltime = 0.1f;
        private float mElapsedtime = 0;

        public int TickCnt { get; private set; }

        public static LongPressListener Get(GameObject go)
        {
            return go.GetComponent<LongPressListener>() ??
                go.AddComponent<LongPressListener>();
        }

        public static LongPressListener Get(UIWidget widget)
        {
            return Get(widget.gameObject);
        }

        public void OnPointerDown(PointerEventData eventData)
        {
            mIsdown = true;
            mElapsedtime = 0;
            TickCnt = 1;
            onEvent?.Invoke(EEvtKind.Down, this);
        }

        public void OnPointerExit(PointerEventData eventData)
        {
            mIsdown = false;
            mElapsedtime = 0;
            TickCnt++;
            onEvent?.Invoke(EEvtKind.Up, this);
            TickCnt = 0;
        }

        public void OnPointerUp(PointerEventData eventData)
        {
            mIsdown = false;
            mElapsedtime = 0;
            TickCnt++;
            onEvent?.Invoke(EEvtKind.Up, this);
            TickCnt = 0;
        }

        public void Update()
        {
            if (mIsdown)
            {
                mElapsedtime += Time.unscaledDeltaTime;
                if (TickCnt == 1)
                {
                    if (mElapsedtime >= mDelaytime)
                    {
                        TickCnt++;
                        onEvent?.Invoke(EEvtKind.Press, this);
                        mElapsedtime = 0;
                    }
                }
                else
                {
                    if (mElapsedtime >= mIntervaltime)
                    {
                        TickCnt++;
                        onEvent?.Invoke(EEvtKind.Press, this);
                        mElapsedtime = 0;
                    }
                }
            }
        }

        public void SetLongPress(float delaytime, float intervaltime = 0)
        {
            mDelaytime = delaytime;
            mIntervaltime = intervaltime;
        }
    }
}
